/* From N6QW using the 160 X 128 TFT Color display with the Si5351 Clock Generator. The sketch includes selectable USB/LSB, a Tune function with 988 Hz tone and the Fout is 1X the LO (operating frequency + offset). Operation on 20 Meters Pete N6QW 05/19/2016 This uses the 9.0 MHZ Filter 8.998500 and 9.001500 USB/LSB GQRP Filtr Zin/out = 500 Ohms This code is written for the LM373 SSB Transceiver -- the LM373 Xcvr was first built in the early 1970 --this is an updated 2017 version TFT pinout information The VCC Pin is not used LED = 3.3 Volts DC SCK = Pin D13 SDA = Pin D11 AO = Pin D9 Reset = Pin D8 CS = Pin D10 GND = Ground Vcc = Not Used Tone = Pin D6 LED = Pin D7 SW = Pin A1 Selects Upper and Lower Sideband SW1 = Pin A2 Slects TUNE Encoder Button = Pin A3 Encoder A = Pin D2 Encoder B = Pin D3 LED = Pin D7 */ #include #include #include // Hardware-specific library #include "Rotary.h" #include #define TONE_PIN 6 #define NOTE_B5 988 #if defined(__SAM3X8E__) #undef __FlashStringHelper::F(string_literal) #define F(string_literal) string_literal #endif #define __CS 10 #define __DC 9 #define __RST 8 #define ENCODER_B 2 // Encoder pin A #define ENCODER_A 3 // Encoder pin B #define ENCODER_BTN A3 // Color definitions #define BLACK 0x0000 #define BLUE 0x001F #define RED 0xF800 #define GREEN 0x07E0 #define CYAN 0x07FF #define MAGENTA 0xF81F #define YELLOW 0xFFE0 #define WHITE 0xFFFF Adafruit_ST7735 display = Adafruit_ST7735(__CS, __DC, __RST); #include "si5351.h" #include "Wire.h" Si5351 si5351; long int frq; int_fast32_t rx = 23201500L; // Starting frequency of VFO operating frequency plus offset which is selectable IF = 9.0 MHz int_fast32_t rx2=1; // variable to hold the updated frequency int_fast32_t increment = 100; // starting VFO update increment in HZ. int_fast32_t bfo = 8998500L; // default offset sideband inversion thus USB String hertz = " 100"; byte ones,tens,hundreds,thousands,tenthousands,hundredthousands,millions ; //Placeholders int buttonstate = 0; int buttonstate2 = 0; const int tonepin = 6; const int SW = A1; //selects upper or lower sideband const int SW1 = A2; // provides the TUNE fucntion const int LED = 7; //When placed in TUNE there is +5 VDC on this pin to control other functions. You could trigger a 2N3904 to close the PTT instead of the MOX switch int backlight =0; int i = 0; int buttonState = 0; int lastButtonState = 0; Rotary r = Rotary(2,3); // sets the pins the rotary encoder uses. Must be interrupt pins. void setup() { Serial.begin(9600); PCICR |= (1 << PCIE2); PCMSK2 |= (1 << PCINT18) | (1 << PCINT19); sei(); //display.begin(); display.initR(INITR_BLACKTAB); display.setRotation(1); // landsacape versus portrait // display.fillScreen(BLACK); pinMode(SW, INPUT); // Selects either USB or LSB````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````[ digitalWrite(SW,HIGH); pinMode(SW1, INPUT); //Tune digitalWrite(SW1,HIGH); pinMode(LED, OUTPUT); digitalWrite(LED,LOW); pinMode(backlight, OUTPUT); pinMode(A3,INPUT); // Connect to a button that goes to GND on push pinMode(A1,INPUT); // IF sense ********************************************** digitalWrite(A3,HIGH); digitalWrite(A2,HIGH); digitalWrite(A1,HIGH); // init done // set backlight level display.fillScreen(BLACK); display.setTextSize(1); display.setTextColor(YELLOW); display.setCursor(20,110); display.println(" LM373 QRP SSB XCVR"); display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(12, 56); display.println(" SB"); //while (!Serial); //tft.begin(); #if defined(__MK20DX128__) || defined(__MK20DX256__) display.setBitrate(24000000); #endif // initialize the Si5351 si5351.init(SI5351_CRYSTAL_LOAD_8PF); si5351.set_correction(100); si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA); si5351.set_freq(rx , SI5351_PLL_FIXED, SI5351_CLK0); si5351.set_freq(bfo, 0, SI5351_CLK2); si5351.drive_strength(SI5351_CLK0,SI5351_DRIVE_8MA); } void setincrement(){ if (increment == 10){increment = 100; hertz = "100";} else if (increment == 100){increment = 1000; hertz=" 1K";} else if (increment == 1000){increment = 10000; hertz=" 10K"; } // else if (increment == 10000){increment = 100000; hertz="100K";} // else if (increment == 100000){increment = 1000000; hertz=" 1M";} else{increment = 10; hertz = " 10";}; delay(150); // Adjust this delay to speed up/slow down the button menu scroll speed. }; void showFreq(){ millions = int(((rx/1)-bfo)/1000000); hundredthousands = ((((rx/1)-bfo )/100000)%10); tenthousands = ((((rx/1)-bfo )/10000)%10); thousands = ((((rx/1)-bfo )/1000)%10); hundreds = ((((rx/1)-bfo )/100)%10); tens = ((((rx/1)-bfo )/10)%10); ones = ((((rx/1)-bfo )/1)%10); display.fillCircle(17,27,10,YELLOW); display.fillCircle(147,27,10,YELLOW); display.fillRect(15,17,135,21,YELLOW); display.setTextSize(2); display.setTextColor(BLACK); if (millions > 9){display.setCursor(24,20);} else{display .setCursor(24,20);} display.print(millions); display.print("."); display.print(hundredthousands); display.print(tenthousands); display.print(thousands); display.setTextColor(BLACK); display.setTextSize(2); display.print("."); display.print(hundreds); display.print(tens); display.print(ones); }; ISR(PCINT2_vect) { unsigned char result = r.process(); if (result) { if (result == DIR_CW){rx=rx+(1*increment);} else {rx = rx-(1*increment);}; if (rx >=23352000){rx=rx2;}; // UPPER VFO LIMIT = 1X the opearting frequency + offset this tunes 14.0 to 14.350 MHz if (rx <=22998500){rx=rx2;}; // LOWER VFO LIMIT = 1 X the opearting frequency + Offset this tunes 14.0 to 14.350 MHz } } void loop() { //tft.setRotation(1); // landsacape versus portrait checkMode(); //********Moved void checkBand out of the loop lastButtonState = buttonState; display.setCursor(140,43); display.setTextColor(YELLOW); display.setTextSize(1); display.print("Hz"); display.setCursor(108, 56); display.setTextColor(GREEN); display.setTextSize(2); display.print("N6QW"); if(digitalRead(SW)){ //********If SW is true do the following. bfo = 9001500L; si5351.set_freq( bfo, 0, SI5351_CLK2);{ if (bfo = 9001500L); display.setTextSize(2); // lets you toggle bewteen USB and LSB without having a screen overwrite display.setTextColor(BLACK); display.setCursor(12,56); display.println("L"); display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(12,56); display.println("U");} } else{ //**********if not, do this. bfo = 8998500L; si5351.set_freq( bfo, 0, SI5351_CLK2); if(bfo= 9001500L); display.setTextSize(2); // lets you toggle bewteen USB and LSB without having a screen overwrite display.setTextColor(BLACK); display.setCursor(12,56); display.println("U"); display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(12, 56); display.println("L"); } if (rx != rx2){ display.setTextSize(2); // When you change frequency you don't have to screen clear! It paints it black display.setTextColor(BLACK); if (millions > 9){display.setCursor(24,20);} else{display .setCursor(24,20);} display.print(millions); display.print("."); display.print(hundredthousands); display.print(tenthousands); display.print(thousands); //tft.setCursor(80,10); display.setTextColor(BLACK); display.setTextSize(2); display.print("."); display.print(hundreds); display.print(tens); display.print(ones); showFreq(); si5351.set_freq(rx , SI5351_PLL_FIXED, SI5351_CLK0); Serial.println(rx); //si5351.set_freq(bfo , SI5351_PLL_FIXED, SI5351_CLK2); rx2 = rx; display.setCursor(110,43); display.setTextColor(YELLOW); display.setTextSize(1); display.print(hertz); } buttonstate = digitalRead(A3); if(buttonstate == LOW) { setincrement(); display.fillRect(110, 40, 140, 10, BLACK); // This blanks the step rate so no overwriting display.setCursor(110,43); display.setTextColor(BLACK); // blanks out the old setting display.setTextSize(1); display.print(hertz); delay(10); display.setCursor(110,43); display.setTextColor(YELLOW); display.setTextSize(1); display.print(hertz); showFreq(); }; delay(25); } void checkMode(){ buttonState = digitalRead(SW1); // creates a 10 second tuning pulse trani 50% duty cycle and makes TUNE appear on the screen if(buttonState != lastButtonState){ if(buttonState == LOW){ digitalWrite(LED,HIGH); display.setTextSize(3); display.setTextColor(RED); display.setCursor(50, 75); display.print("TUNE"); //display.display(); delay(12); for(int i = 0; i < 100; i++) { tone(6, NOTE_B5); delay(50); noTone(6); delay(50); } } else{ digitalWrite(LED,LOW); display.setTextSize(3); // This prints a Black TUNE over the RED TUNE and makes it disappear from the scereen display.setTextColor(BLACK); display.setCursor(50, 75); display.print("TUNE"); noTone(6); } delay(50); } }